package org.trajectory.web.rest.resources;

import java.io.IOException;

import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response.Status;

import org.jdom.JDOMException;
import org.pentaho.platform.api.engine.IPentahoSession;
import org.pentaho.platform.api.engine.ISolutionFile;
import org.pentaho.platform.api.engine.PentahoAccessControlException;
import org.pentaho.platform.api.repository.ISolutionRepository;
import org.pentaho.platform.engine.core.solution.ActionInfo;
import org.pentaho.platform.engine.core.system.PentahoSessionHolder;
import org.pentaho.platform.engine.core.system.PentahoSystem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.trajectory.plugin.util.PluginConfig;
import org.trajectory.query.Query;
import org.trajectory.query.QueryDeserializer;
import org.trajectory.query.QuerySerializer;
import org.trajectory.query.SavedQuery;

@Component
@Path("/trajectory/{datasource}/{shop}/repository")
public class QueryRepository {
	private static final Logger log = LoggerFactory.getLogger(QueryRepository.class);
	@POST
	@Produces({"application/json"})
	@Path("/{queryName}")
	public void saveQuery(@PathParam("queryName") String queryName , @PathParam("datasource") String datasource,
			@PathParam("shop") String shop,@FormParam("trajectory") String trajectory,
			@FormParam("from") Long from, @FormParam("to") Long to ,@FormParam("solution") String solution , @FormParam("path") String path , @FormParam("action") String action) throws Exception{
		Query query = new Query();
		query.setDatasource(datasource);
		query.setShop(shop);
		query.setLine(trajectory.split(","));
		query.setFrom(from);
		query.setTo(to);
		QuerySerializer serializer = new QuerySerializer(query);
		String xml = serializer.createXML();	
		if (!action.endsWith(PluginConfig.PLUGIN_SUFFIX)) {
			action += PluginConfig.PLUGIN_SUFFIX;
		}
		String fullPath = ActionInfo.buildSolutionPath(solution, path, action);
		IPentahoSession userSession = PentahoSessionHolder.getSession();
		ISolutionRepository repository = PentahoSystem.get(ISolutionRepository.class, userSession);

		if( repository == null ) {
			log.error("Access to Repository has failed");
			throw new NullPointerException("Access to Repository has failed");
		}
		String base = PentahoSystem.getApplicationContext().getSolutionRootPath();
		String parentPath = ActionInfo.buildSolutionPath(solution, path, "");
		ISolutionFile parentFile = repository.getSolutionFile(parentPath, ISolutionRepository.ACTION_CREATE);
		String filePath = parentPath + ISolutionRepository.SEPARATOR + action;
		ISolutionFile fileToSave = repository.getSolutionFile(fullPath, ISolutionRepository.ACTION_UPDATE);

		if (fileToSave != null || (!repository.resourceExists(filePath) && parentFile != null)) {
			repository.publish(base, '/' + parentPath, action, xml.getBytes() , true);
			log.debug(PluginConfig.PLUGIN_NAME + " : Published " + solution + " / " + path + " / " + action );
		} else {
			throw new Exception("Error ocurred while saving query to solution repository");
		}
	}
	@GET
	@Produces(MediaType.APPLICATION_JSON)
	@Path("/{name}")
	public Query loadQuery(@PathParam("name") String name,
			@QueryParam("solution") String solution,
			@QueryParam("path") String path,
			@QueryParam("action") String action) throws IOException, JDOMException{
		
		if (!action.endsWith(PluginConfig.PLUGIN_SUFFIX)) {
			action += PluginConfig.PLUGIN_SUFFIX;
		}
		
		String fullPath = ActionInfo.buildSolutionPath(solution, path, action);
		IPentahoSession userSession = PentahoSessionHolder.getSession();
		ISolutionRepository repository = PentahoSystem.get(ISolutionRepository.class, userSession);


		if (repository.resourceExists(fullPath)) {
			String doc = repository.getResourceAsString(fullPath, ISolutionRepository.ACTION_EXECUTE);
			if (doc == null) {
				log.error("Error retrieving saiku document from solution repository"); 
				throw new NullPointerException("Error retrieving saiku document from solution repository"); 
			}
		return new QueryDeserializer(doc).parse();
		}
		return null;
	}
		
}
